fix: avoid cctype UB, dedupe msvc-runtime errors, use std::any_of - #203
fix: avoid cctype UB, dedupe msvc-runtime errors, use std::any_of#203Wael-MA wants to merge 3 commits into
Conversation
| #include "fs.hpp" | ||
| #include "project_parser.hpp" | ||
| #include <algorithm> | ||
| #include <cctype> // Wael-MA: we call isspace below, better to include it explicitly |
| return false; | ||
| // Wael-MA: swapped the manual scan for std::any_of, behavior is the same | ||
| return std::any_of(sources.begin(), sources.end(), [&project_extensions](const std::string &source) { | ||
| return project_extensions.count(fs::path(source).extension().string()) > 0; |
There was a problem hiding this comment.
I don't think this is any easier to read and std::any_of has horrible codegen in debug mode, don't think it's worthwhile.
| // Wael-MA: std::any_of does the same scan, just a lot easier to read | ||
| using value_type = std::pair<std::string, std::vector<std::string>>; | ||
| return std::any_of(includes.begin(), includes.end(), | ||
| [](const value_type &itr) { return !itr.second.empty(); }); |
There was a problem hiding this comment.
Same comment as above, I don't think this makes the code any easier to read.
| // Make sure the file ends in a single newline | ||
| while (!generated_cmake.empty() && std::isspace(generated_cmake.back())) { | ||
| // Wael-MA: isspace must receive an unsigned char, plain chars can be negative | ||
| while (!generated_cmake.empty() && std::isspace(static_cast<unsigned char>(generated_cmake.back()))) { |
| @@ -657,7 +664,9 @@ Project::Project(const Project *parent, const std::string &path, bool build) : p | |||
|
|
|||
| auto is_cmake_arg = [](const std::string &s) { | |||
| for (auto c : s) { | |||
There was a problem hiding this comment.
Change this to unsigned char c : s and then you don't have to touch the code below
| @@ -695,7 +704,8 @@ Project::Project(const Project *parent, const std::string &path, bool build) : p | |||
| throw_key_error("Empty hash value", argItr.first, argItr.second); | |||
| } | |||
| for (char c : value) { | |||
| @@ -1308,7 +1312,9 @@ bool Project::cmake_minimum_version(int major, int minor) const { | |||
|
|
|||
| bool Project::is_condition_name(const std::string &name) { | |||
| for (auto ch : name) { | |||
|
Hey mrexodia, I've done the changes you told me to. And removed all "// Wael-MA:" comments. Hope you approve. |
|
The CI is failing and it needs clang-format, but otherwise mostly good. |
|
Done, no conflicts with base branch now |
|
Sorry this is not reviewable, I will redo it myself in a simpler way. |
|
Thanks for your contribution. I redid the changes and committed directly on main. |
Summary
Three small, behavior-preserving cleanups across the parser/generator:
Avoid UB from
<cctype>calls on signedchar—std::isdigit,std::isupper,std::isxdigit,std::isalnum, andstd::isspacewere being passed rawchars, which is undefined behavior for negative (non-ASCII) bytes. Cast tounsigned charat each call site and include<cctype>explicitly incmake_generator.cpp.De-duplicate the
msvc-runtimeerror builder — the same "Unknown runtime..." message was built in two places; extracted into a sharedmsvc_runtime_error()helper that also avoids per-iterationstd::stringallocations (const char *loop).Replace manual scan loops with
std::any_of—contains_language_sourceandhas_includenow use the standard algorithm, which reads the intent directly and short-circuits identically.Testing
cmake -B build+cmake --buildpasses cleanly (C++11 target).